package data

import (
	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"kratos-realworld/internal/conf"
)

// 可以理解为 NewData, NewDB, NewGreeterRepo 这些方法都有 @Bean 的标记，会被 wire 扫描到
var ProviderSet = wire.NewSet(NewData, NewDB, NewUserRepo, NewProfileRepo, NewArticleRepo, NewCommentRepo, NewTagRepo)

// Data .
type Data struct {
	db *gorm.DB
}

// 可以理解为，NewData 方法注入了一个外部的 Bean(*gorm.DB) 也就是 NewDB。 需要注意的是，wire 只有类型注入，没有名称注入，相同的多个类型的 Bean 会被覆盖
func NewData(c *conf.Data, logger log.Logger, db *gorm.DB) (*Data, func(), error) {
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	return &Data{db: db}, cleanup, nil
}

func NewDB(c *conf.Data) *gorm.DB {
	db, err := gorm.Open(mysql.Open(c.Database.Dsn), &gorm.Config{
		// 创建表时不建立外键关系
		DisableForeignKeyConstraintWhenMigrating: true,
	})
	if err != nil {
		panic("failed to connect database")
	}
	InitDB(db)
	return db
}

func InitDB(db *gorm.DB) {
	// 根据实体定义，自动创建表
	if err := db.AutoMigrate(&User{}); err != nil {
		panic(err)
	}
}
